package com.robusta.app.catalogue.service;

import com.google.common.base.Function;
import com.robusta.app.catalogue.api.CatalogueOperations;
import com.robusta.app.catalogue.model.CatalogueEntryModel;
import com.robusta.app.catalogue.persistence.CatalogueRepository;
import com.robusta.app.domain.Domain;
import com.robusta.app.domain.YesNo;
import com.robusta.app.domain.catalogue.CatalogueEntry;
import com.robusta.app.domain.data.Pageable;
import com.robusta.app.domain.data.Searchable;
import com.robusta.app.domain.data.Sortable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.google.common.collect.Lists.transform;

@Service
public class CatalogueTemplate implements CatalogueOperations {
    private CatalogueRepository catalogueRepository;

    @Autowired
    public CatalogueTemplate(CatalogueRepository catalogueRepository) {
        this.catalogueRepository = catalogueRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public int searchCountFor(Searchable searchable) {
        return catalogueRepository.countOfEntriesMatching(searchable);
    }

    @Override
    @Transactional(readOnly = true)
    public List<CatalogueEntry> searchEntries(Searchable searchable, Pageable pageable, Sortable sortable) {
        List<CatalogueEntryModel> catalogueEntries = catalogueRepository.searchForEntries(searchable, pageable, sortable);
        return transform(catalogueEntries, new Function<CatalogueEntryModel, CatalogueEntry>() {
            @Override
            public CatalogueEntry apply(CatalogueEntryModel input) {
                return aCatalogueEntry(input.getId(), input.getDescription(), input.getDomain(), input.getLaterallyEnabled(), input.getActive());
            }
        });
    }

    public CatalogueEntry aCatalogueEntry(long id, String description, Domain domain, YesNo laterallyEnabled, YesNo active) {
        return new CatalogueEntryImpl(id, description, domain, laterallyEnabled, active);
    }

    private class CatalogueEntryImpl implements CatalogueEntry {
        private final long id;
        private final String description;
        private final Domain domain;
        private final YesNo laterallyEnabled;
        private final YesNo active;

        public CatalogueEntryImpl(long id, String description, Domain domain, YesNo laterallyEnabled, YesNo active) {
            this.id = id;
            this.description = description;
            this.domain = domain;
            this.laterallyEnabled = laterallyEnabled;
            this.active = active;
        }

        @Override
        public Long id() {
            return id;
        }

        @Override
        public String description() {
            return description;
        }

        @Override
        public Domain domain() {
            return domain;
        }

        @Override
        public YesNo laterallyEnabled() {
            return laterallyEnabled;
        }

        @Override
        public YesNo active() {
            return active;
        }
    }
}
